#include <stdlib.h>
#include <stdio.h>
#include "stack.h"

struct sStack
{
	tsalpha * elems;
	int tam;
	int maxTam;
};

Bool
stack_full(const Stack s);

Stack
stack_empty(const tspos max)
{
	Stack s = NULL;
	
	s = (Stack) malloc (sizeof(struct sStack));
	if (s!=NULL)
	{
		s->elems = (tsalpha *) calloc (max+1, sizeof(tsalpha)); /*uso desde 1 hasta max*/
		if (s->elems != NULL)
		{
			s->tam = 0;
			s->maxTam = max;
		}	
		else
		{
			free(s);
			s = NULL;
			perror("No hay memoria para nueva pila (stack_empty)");
			exit(EXIT_FAILURE);
		}
	}
	else
	{
		perror("No hay memoria para nueva pila (stack_empty)");
		exit(EXIT_FAILURE);
	}
return s;
}

void
stack_push(Stack s, tsalpha elem)
{
	tsalpha aux;
	
	if (!(stack_full(s)))
	{
		aux = tsalpha_clone(elem);
		s->tam += 1;
		s->elems[s->tam] = aux;
	}
	else
		printf("Warn: se intento apilar en una pila llena. La pila permanece llena\n");
}

tsalpha
stack_top(const Stack s)
{
	tsalpha ret;

	if(isEmpty_stack(s))
	{
		perror("No se puede obtener el primer elemento de una pila vacía\n");
		exit(EXIT_FAILURE);
	}
	else
		ret = tsalpha_clone(s->elems[s->tam]);
return ret;
}


void
stack_pop(Stack s)
{
	if(isEmpty_stack(s))
		printf("Warn: Se intento desapilar una pila vacia. La pila permanece vacia\n");
	else
	{
		s->elems[s->tam] = tsalpha_destroy(s->elems[s->tam]);
		s->tam -= 1;
	}
}

Bool
isEmpty_stack(const Stack s)
{
	Bool b;
	b = (s->tam == 0);
return b;
}

Stack
stack_destroy(Stack s)
{
	if (s!=NULL)
	{
		while(!isEmpty_stack(s))
			stack_pop(s);
	
		if (s->elems != NULL)
		{	
			free(s->elems);
			s->elems = NULL;
		}
		free(s);
		s = NULL;
	}
return s;
}

Bool
stack_full(const Stack s)
{
	Bool b;
	b = (s->tam == s->maxTam);
return b;
}
